home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / comm / ns_16550.zip / IFIFO.C < prev    next >
Text File  |  1991-07-20  |  15KB  |  355 lines

  1. /* ififo.c     11/4/88    Louis Shay
  2.    This function is used to test basic FIFO functions of a NS16550A
  3.    or compatible UART channel at the system base address " int  ubase ". 
  4.    This address must be defined in the calling program.
  5.    Program requirements.
  6.  
  7.      1. #include <stdio.h>
  8.     #include <conio.h>
  9.     #include "ns16550a.h" must be in the main() source file.
  10.      2. Integer variables ubase and fatal_error must be declared as 
  11.         global values in the main() source program.
  12.      3. The  caller must set ubase to the device's base address before
  13.         calling ififo().
  14.      4. This program assumes basic 450-mode functionality, therefore
  15.         i450() should first be run and the fatal_error flag clear before
  16.         calling ififo(). The calling sequence in main() should be:
  17.  
  18.     1. Call i450()       - this tests basic functionality
  19.     2. IF ( fatal_error == 0 )
  20.               call ififo()
  21.            ELSE 
  22.               quit testing this UART channel.
  23.  
  24.    Hardware Requirements:
  25.       1. The UART I/O input pins SIN, CTS, DCD, DSR, RI, must
  26.          be pulled high and not driven by external sources during
  27.          this test, otherwise false errors may be generated.
  28.  
  29.    Error messages printed will be in the form " Error (n)...", where 
  30.    n refers to the section of this source program.               
  31. */
  32.  
  33. #include <stdio.h>
  34. #include <conio.h>
  35. #include "ns16550a.h"
  36.  
  37. #define TIMEOUT 10000
  38.  
  39. int ififo()
  40. {
  41.   extern int ubase, fatal_error;
  42.   int rbrval, iirval, lsrval, tx_data = 0, rx_data = 0;
  43.   int error_count = 0, count_a, count_b, trigger, x=0;
  44.  
  45. /* 0. start test */
  46.   printf("\nNS16550A FIFO functions test...\n");
  47.  
  48. /* 1. Initialize FIFO mode and check FIFO init. state */
  49.  
  50.   wrLCR( 0x80 );                /* LCR = 80h, set DLAB */
  51.   wrDLL( 0x9c );                /* DLL, 9600 baud @ 1.8MHz input */
  52.   wrDLM( 0 );
  53.   wrLCR( 0x03 );                /* LCR: 8 data, 1 stop, no pty. */
  54.   wrMCR( 0x10 );                /* MCR: internal loopback mode */
  55.   wrFCR( 0xcf );                /* FCR: fifo mode 1, reset, trigger=14 */
  56.   wrIER( 0x0f );                /* IER: interrupts on */
  57.  
  58.   iirval = rdIIR();             /* check ID bits */
  59.   lsrval = rdLSR();             /* check THRE and DR */
  60.   rbrval = rdRBR();             /* check rbr = 00h */
  61.  
  62.   if( ( iirval & 0xc0 ) != 0xc0 ) { /* no ID bits - fatal error */
  63.     printf(" Error (1)..FIFO ID bits not set! IIR = %2x\n", iirval );
  64.     error_count += 1;
  65.     goto ABORT;
  66.   }
  67.   if( lsrval != 0x60 ) {
  68.     printf(" Error (1)..FIFO init. error : LSR = %2x\n", lsrval );
  69.     error_count += 1;
  70.   }
  71.   if( rbrval != 0 ) {
  72.     printf(" Error (1)..FIFO init. error : RBR = %2x\n", rbrval );
  73.     error_count += 1;
  74.   }
  75.   if( ( iirval & 0x0f ) != 2 ) {
  76.     printf(" Error (1)..FIFO init. error : IIR = %2x\n", iirval );
  77.     error_count += 1;
  78.   }
  79.  
  80.  
  81. /* 2. Test basic FIFO functions - loop a character */
  82.     
  83.   wrTHR( 0x55 );                        /* send a byte */
  84.   while( !( rdLSR() & 0x40 )) ;         /* poll LSR until TEMT is set */
  85.   lsrval = rdLSR();                     /* test for rx data and lsr clean */
  86.   rbrval = rdRBR();
  87.   if(((lsrval & 0x01 ) == 0 )||(( lsrval & 0x1e ) != 0 )||( rbrval != 0x55 ))
  88.   { /* if DR = 0, or OE/PE/FE/BI set, or rbr not 55h, then error */
  89.     printf(" Error (2)..Tx / Rx 1st read: LSR = %2x RBR = %2x (55H)\n",
  90.              lsrval, rbrval );
  91.     error_count += 1;
  92.   }
  93.   lsrval = rdLSR();             /* test for FIFO empty condition - read again */
  94.   rbrval = rdRBR();
  95.   if((( lsrval & 0x01 ) == 1 )||(( lsrval & 0x9e ) != 0 )||( rbrval != 0x00 ))
  96.   { /* if DR = 1, or OE/PE/FE/BI/EIF set, or RBR not 00h, then error */
  97.     printf(" Error (2)..Tx / Rx 2nd read: LSR = %2x RBR = %2x (00H)\n",
  98.              lsrval, rbrval );
  99.     error_count += 1;
  100.   }
  101.  
  102.  
  103. /* 3. Test FIFO reset functions - FCR & LSR */
  104.  
  105.   for( count_a = 1 ; count_a <=  16 ; count_a++ )   /* fill tx FIFO */
  106.      wrTHR( count_a );
  107.  
  108.   wrFCR( 0xcd );                     /* reset tx fifo but not rx fifo */
  109.   lsrval = rdLSR();
  110.   if( ( lsrval & 0x20 ) == 0 ) { /* if reset, THRE = 1  */
  111.     printf(" Error (3)..Tx FIFO reset : LSR = %2x\n", lsrval );
  112.     error_count += 1;
  113.   }
  114.  
  115.   wrFCR( 0 );                   /* reinitialize fifo's */
  116.   wrFCR( 0xcf );                /* trigger=14, cleared, mode 1 */
  117.  
  118.   while ( !( rdLSR() & 0x40 )) ;        /* poll TEMT until set */
  119.   wrFCR( 0xcf );                        /* reset FIFO */
  120.   lsrval = rdLSR();                     /* read status */
  121.   rbrval = rdRBR();
  122.   if( (( lsrval & 0x01 ) == 1 ) || ( rbrval != 0 ) ) {
  123.     printf(" Error (3)..Rx FIFO reset : LSR = %2x RBR = %2x\n", lsrval,
  124.              rbrval );
  125.     error_count += 1;
  126.   }
  127.  
  128.  
  129. /* 4. Test FIFO-mode loop transfers 00 to ff (16 byte blocks) 
  130.        This section sends 16 blocks of 16 bytes each, and compares
  131.       receiver data to transmitted data. LSR values for each byte received
  132.        are also checked. At the end of each 16 bytes received, the RBR
  133.       is read a 17th time to check for a FIFO empty condition.*/
  134.  
  135.   wrLCR( 0x80 );        /* init. UART */
  136.   wrDLL( 0x0c );        /* 9600 baud */
  137.   wrDLM( 0 );
  138.   wrLCR( 0x0f );        /* LCR : 8 data, 2 stops, odd pty */
  139.   wrFCR( 0 );
  140.   wrFCR( 0xcf );        /* FCR : trigger=14, mode 1, cleared */
  141.   wrIER( 0 );           /* interrupts off */
  142.   (void)rdRBR();           /* clear registers */
  143.   (void)rdLSR();
  144.   (void)rdMSR();
  145.   tx_data = 0;        /* init tx data byte */
  146.   rx_data = 0;        /* init rx comparitor byte */
  147.  
  148.   /* loopback test loop 16 x 16 = 256 bytes sent */
  149.   for( count_a = 1 ; count_a <= 16 ; count_a++ ) {
  150.       (void)rdRBR();             /* dummy read */
  151.      for( count_b = 1 ; count_b <= 16 ; count_b++ ) {
  152.     wrTHR( tx_data++ );      /* load tx FIFO with counter data */
  153.      }
  154.      while( !( rdLSR() & 0x40 )) ;      /* wait for TEMT set */
  155.      for( count_b = 1 ; count_b <= 16 ; count_b++ ) {
  156.     lsrval = rdLSR();       /* check rx FIFO contents */
  157.     rbrval = rdRBR();
  158.     if( (( lsrval & 0x9f ) != 1 ) || ( rbrval != ( rx_data & 0xff )) )
  159.         { /* if DR = 0, or OE/PE/FE/BI/EIF set, or rbrval != Tx_data, then..*/
  160.           printf(" Error (4)..FIFO data: read=%d  LSR=%2x  RBR=%2x  TX=%2x\n",
  161.                    count_b, lsrval, rbrval, rx_data );
  162.           error_count += 1;
  163.         }
  164.         rx_data += 1;        /* increment comparator */
  165.      }
  166.      lsrval = rdLSR();          /* check for FIFOs empty */
  167.      rbrval = rdRBR();
  168.      if( ( lsrval != 0x60 ) || ( rbrval != 0 ) ) {
  169.        printf(" Error (4)..FIFO not empty: read=17  LSR=%2x  RBR=%2x\n",
  170.                 lsrval, rbrval );
  171.        error_count += 1;
  172.      }
  173.   }
  174.  
  175. /* 5. Test IIR / Rx FIFO trigger levels 
  176.        For each of the four trigger levels, this test will:
  177.        1. Fill the Rx FIFO to trigger - 1.
  178.           check for NO interrupt.
  179.        2. Send one byte. Reach receiver trigger level.
  180.           check for DR interrupt set.
  181.        3. Read a byte from RBR - drop below trigger level.
  182.           check for interrupt clear. */
  183.  
  184.   for( count_a = 0 ; count_a <= 3 ; count_a++ ) 
  185.   { /* test each of the four trigger levels for IIR set & reset */
  186.  
  187.      wrFCR( 0 );                /* reset FIFOs to char mode */
  188.      wrIER( 0 );                /* reset interrupts */
  189.      wrIER( 0x05 );             /* IER : enable RDAI, LSI */
  190.      while( !( rdLSR() & 0x40 )) ;      /* poll TEMT until set */
  191.      /* fill rx FIFO to 1 byte under trigger level */
  192.      switch( count_a ) {
  193.        case 0: wrFCR( 0x0f );           /* trigger = 1 */
  194.                trigger = 1;
  195.                break;            /* send 0 bytes */
  196.  
  197.        case 1: wrFCR( 0x4f );           /* trigger = 4 */
  198.                trigger = 4;
  199.            for( count_b = 1 ; count_b <= 3 ; count_b++ )
  200.           wrTHR( count_b );     /* send 3 bytes */
  201.                break;
  202.  
  203.        case 2: wrFCR( 0x8f );           /* trigger = 8 */
  204.                trigger = 8;
  205.                for( count_b = 1 ; count_b <= 7 ; count_b++ )
  206.           wrTHR( count_b );     /* send 7 bytes */
  207.                break;
  208.  
  209.        case 3: wrFCR( 0xcf );           /* trigger = 14 */
  210.